xlv.object={
	construct:function(){
	},
	initial:function(){
	},
	disposable:function(){
		return true;
	},
	dispose:function(){
	},
	message:function(memo){
	},
	$super:function(qname){
		try{
			var args=$A(arguments);
			args.shift();
			var names=qname.split(/\./);
			return xlv[names[1]][names[2]]['method'][names[3]].apply(this,[].concat(args));
		}catch(e){alert('$super('+qname+') apply exception :\n'+e);}
	},
	$self:function(fname){
		var ext=this._$exts;
		try{
			if(ext&&ext.length>=1){
				var args=$A(arguments);
				args.shift();
				var index=ext.length-1;
				while(index>=0){
					var names=ext[index].split(/\./);
					var f=xlv.obj[names[names.length-1]]['method'][fname];
					if(f) return f.apply(this,[].concat(args));
					--index;
				}
				alert('$self('+fname+') apply exception : method not found');
			}
		}catch(e){alert('$self('+fname+') apply exception :\n'+e);}
	},
	objectName:function(){
		return this.getAttribute('xlvobject');
	},
	getFrameById:function(id){
		var attribute={xlvobject:'xlv.obj.frame'};
		if(id)attribute.id=id;
		if(xlv.util.matchAttributes(this,attribute))return this;
		return xlv.util.findParent(this,attribute);
	},
	getPaneById:function(id){
		var attribute={xlvobject:'xlv.obj.pane'};
		if(id)attribute.id=id;
		if(xlv.util.matchAttributes(this,attribute))return this;
		return xlv.util.findParent(this,attribute);
	},
	getBorderLayoutById:function(id){
		var attribute={xlvobject:'xlv.obj.borderLayout'};
		if(id)attribute.id=id;
		if(xlv.util.matchAttributes(this,attribute))return this;
		return xlv.util.findParent(this,attribute);
	},
	getParentById:function(id){
		return xlv.util.findParent(this,{'id':id},false);
	},
	getDesktop:function(){
		return xlv.desktop;
	},
	getDataModel:function(dm_name){
		dm_name=(dm_name||this.$P.dmName);
		return xlv.util.dmSearch(this,dm_name);
	},
	getObjects:function(element,object_name){
		return xlv.util.getObjects((element||this),object_name);
	},
	getObjectById:function(id){
		var element=xlv.util.findChild(this,{'id':id},false,false);
		if(!element){
			var xobj,p=this.parentNode,t=this;
			while(p){
				if(p.nodeType==1 && (xobj=p.getAttribute('xlvobject'))){
					if(p.id==id)return p;
					if(xobj=='xlv.obj.pane'||xobj=='xlv.obj.borderLayout'||xobj=='xlv.obj.layerPanes'||xobj=='xlv.obj.frame'){
						if(element=xlv.util.findChild(p,{'id':id},false,{object:t}))return element;
						t=p;
					}
				}
				p=p.parentNode;
				if(p==document.body)break;
			}
		}
		return element;
	},
	isDisplayNone:function(){
		return xlv.util.isDisplayNone(this);
	},
	extend:function(extend_xlvobject){
		try{
			/*convert to object name*/
			var f=extend_xlvobject.strip();
			/*check extended*/
			if((this._$exts=(this._$exts||[])).include(f)) return;
			/*recursive call extend*/ 
			eval(f+'.extend.call(this)');
			/*extend this f*/
			eval('Object.extend(this,'+f+'.method)');
			/*recursive call implement*/
			eval(f+'.implement.call(this)');
			/*extend this f properties*/
			this.properties=this.properties||{};
			///?????????the RegExp JSON not work
			eval('Object.extend(this.properties, Object.toJSON('+f+'.properties).evalJSON())');
			//eval('Object.extend(this.properties,'+f+'.properties)');
			/*resolve HTML properties*/
			var xlvprop=this.getAttribute('xlvprop');
			Object.extend(this.properties,(xlvprop)? xlvprop.evalJSON():{});
			/*shortcut support*/ 
			this.properties._$var={};
			/*shortcut for properties*/
			this.$P=this.properties;
			/*shortcut for properties._$var*/
			this.$V=this.properties._$var;
			//remember this f
			this._$exts.push(f);
			//extend xlvmethod
			var xlvmethod=this.getAttribute('xlvmethod');
			Object.extend(this,(xlvmethod)? xlvmethod.evalJSON():{});
		}catch(e){alert('extend error: '+f+' \n--'+e);}
	},
	implement:function(implemnt_xlvimp){
		try{
			/*convert to object name*/
			var f=implemnt_xlvimp.strip();
			/*check had implemented*/
			if((this._$imps=(this._$imps||[])).include(f)) return;
			/*implement this f*/
			eval('Object.implement(this,'+f+'.method)');
			/*recursive call implement*/
			eval(f+'.implement.call(this)');
			this._$imps.push(f);
		}catch(e){alert('implement error: '+e);}
	},
	isImplement:function(implemnt_xlvimp){
		return this._$imps ? this._$imps.include(implemnt_xlvimp.strip()) : false;
	},
	isExtend:function(extend_xlvobject){
		return this._$exts ? this._$exts.include(extend_xlvobject.strip()) : false;
	},
	targetElement:function(src,attributes,boundary){
		if(!src||src.nodeType!=1)return null;
		do {
			if(boundary && xlv.util.matchAttributes(src,boundary))return null;
			if(xlv.util.matchAttributes(src,attributes))return src;
			if(src==this)return null;
		}while(src=src.parentNode);
		return null;
	},
	queueTimeout:function(function_object){
		if(!this.$V.__timeoutQueue)this.$V.__timeoutQueue=[];
		if(function_object)this.$V.__timeoutQueue.push(function_object);
		if(!this.$V.__timeoutHandler&&this.$V.__timeoutQueue.length>0){
			this.$V.__timeoutHandler=setTimeout(function(){
				var func=this.$V.__timeoutQueue.shift();
				func();
				this.$V.__timeoutHandler=null;
				this.queueTimeout(null);
			}.bind(this), 1);
		}
	},
	wait:function(options,function_object){
		if(!this.$V.__waitQueue)this.$V.__waitQueue=[];
		if(options&&function_object)this.$V.__waitQueue.push({'options':options, func:function_object});
	},
	notified:function(options){
		if(!this.$V.__waitQueue)this.$V.__waitQueue=[];
		for(var i=0,n=this.$V.__waitQueue.length;i<n;++i){
			var wait_options=this.$V.__waitQueue[i].options;
			var match=true;
			for(var p in wait_options){
				if(wait_options[p]!=options[p]){
					match=false;
					break;
				}
			}
			if(match){
				this.queueTimeout(this.$V.__waitQueue[i].func);
				//var func=this.$V.__waitQueue[i].func;
				//func();
				this.$V.__waitQueue[i]=null;
			}
		}
		this.$V.__waitQueue=this.$V.__waitQueue.compact();
	},
	addEventHandler:function(event_name,function_name,element){
		this._$evtCache=(this._$evtCache||[]);
		var a=[event_name,(function_name||event_name),element];
		//IE notify seq reverse 
		if(Prototype.Browser.IE) this._$evtCache.unshift(a);
		else this._$evtCache.push(a);
		if(this._$observed){
			Event.observe((element||this),event_name,a[3]=xlv.util.bindAsEventListener(this, function_name), false);
		}
	},
	listObserve:function(){
		var tmp='';
		var as=(this._$evtCache||[]);
		for(var i=0,n=as.length;i<n;++i){
			tmp +='event :'+as[i][0]+'  '+as[i][1]+'\n';
		}
		alert(''+tmp);
	},
	startObserve:function(){
		if(this._$observed)return;
		var as=(this._$evtCache||[]);
		for(var i=0,n=as.length;i<n;++i){
			if(typeof this[as[i][1]] == 'function'){
				Event.observe((as[i][2]||this), as[i][0], as[i][3]=xlv.util.bindAsEventListener(this, as[i][1]), false);
			}else alert('this event listener: '+as[i][1]+' is not a function or undefined');
		}
		this._$observed=true;
	},
	removeObserve:function(event_name,function_name,element){
		var as=(this._$evtCache||[]);
		for(var i=0,n=as.length;i<n;++i){
			if(as[i][0]==event_name&&as[i][1]==function_name&&as[i][2]==element){
				Event.stopObserving(element,event_name,as[i][3]);
				as.splice(i,1);
				return;
			}
		}
	},
	stopObserve:function(){
		this._$observed=false;
		Event.stopObserving(this, null, null);
		var as=(this._$evtCache||[]);
		for(var i=0,n=as.length;i<n;++i){
			if(as[i][2])Event.stopObserving(as[i][2],as[i][0],null);
		}
	},
	pauseObserve:function(){
		this._$observeFlagStack=(this._$observeFlagStack||[]);
		this._$observeFlagStack.push(this._$observeFlag);
		this._$observeFlag=false;
	},
	restoreObserve:function(){
		this._$observeFlagStack=(this._$observeFlagStack||[]);
		this._$observeFlag=this._$observeFlagStack.pop();
	},
	isObserving:function(){
		return this._$observeFlag;
	},
	/*donot modified flag directly*/
	_$observeFlag:true,
	_$observeFlagStack:null
};
